package com.sky.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersPaymentDTO;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.entity.*;
import com.sky.exception.BaseException;
import com.sky.exception.OrderBusinessException;
import com.sky.mapper.*;
import com.sky.result.PageResult;
import com.sky.service.UserOrderService;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.webSocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zcf
 */
@Service
@Slf4j
public class UserOrderServiceImpl implements UserOrderService {
    @Resource
    private UserOrderMapper userOrderMapper;

    @Resource
    private UserMapper userMapper;
    @Resource
    private AddressBookMapper addressBookMapper;

    @Resource
    private ShoppingCartMapper shoppingCartMapper;

    @Resource
    private OrderDetailMapper orderDetailMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO) {
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO, orders);
        //1.查询地址信息
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        if (addressBook == null) {
            throw new BaseException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }
        //2.1查询购物车信息
        ShoppingCart shoppingCart = ShoppingCart.builder().userId(BaseContext.getCurrentId()).build();
        List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);
        if (CollectionUtils.isEmpty(list)) {
            throw new BaseException(MessageConstant.SHOPPING_CART_IS_NULL);
        }
        //1.保存订单
        //生成订单号
        orders.setNumber(String.valueOf(System.nanoTime()));
        orders.setUserId(BaseContext.getCurrentId());
        orders.setOrderTime(LocalDateTime.now());
        orders.setStatus(Orders.PENDING_PAYMENT);
        //未支付
        orders.setPayStatus(Orders.UN_PAID);
        orders.setAddress(addressBook.getDetail());
        orders.setConsignee(addressBook.getConsignee());
        orders.setPhone(addressBook.getPhone());
        //2.查询用户名称
        User user = userMapper.getById(BaseContext.getCurrentId());
        orders.setUserName(user.getName());
        //3.保存
        userOrderMapper.insert(orders);
        //2.保存订单明细
        OrderDetail orderDetail = new OrderDetail();
        List<OrderDetail> collect = list.stream().map(
                shoppingCart1 -> {
                    BeanUtils.copyProperties(shoppingCart1, orderDetail);
                    //订单号
                    orderDetail.setOrderId(orders.getId());
                    return orderDetail;
                }
        ).collect(Collectors.toList());

        orderDetailMapper.insertBatch(collect);
        return OrderSubmitVO.builder().id(orders.getId()).orderTime(orders.getOrderTime()).orderAmount(orders.getAmount())
                .orderNumber(orders.getNumber()).build();
    }

    @Override
    /**
     * 订单支付
     *
     * @param ordersPaymentDTO
     * @return
     */
    public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) {

       /* //调用微信支付接口，生成预支付交易单
        JSONObject jsonObject = weChatPayUtil.pay(
                ordersPaymentDTO.getOrderNumber(), //商户订单号
                new BigDecimal(0.01), //支付金额，单位 元
                "苍穹外卖订单", //商品描述
                user.getOpenid() //微信用户的openid
        );*/

        JSONObject jsonObject = new JSONObject();
        //查询该订单状态是否已支付
        Orders orders = userOrderMapper.getByNumberAndUserId(ordersPaymentDTO.getOrderNumber(), BaseContext.getCurrentId());
        if (orders.getPayStatus() == Orders.PAID) {
            throw new OrderBusinessException("该订单已支付");
        }

        OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);
        vo.setPackageStr(jsonObject.getString("package"));

        return vo;
    }


    /**
     * 查询历史订单
     *
     * @param page
     * @param pageSize
     * @param status
     * @return
     */
    @Override
    public PageResult list(int page, int pageSize, Integer status) {
        //1.设置分页参数
        PageHelper.startPage(page, pageSize);
        //2.查询订单
        List<Orders> list = userOrderMapper.list(BaseContext.getCurrentId(), status);
        Page<Orders> orders = (Page<Orders>) list;
        List<OrderVO> list1 = new ArrayList<>();
        //3.查询订单明细
        if (list != null && list.size() > 0) {
            for (Orders order : orders) {
                List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(order.getId());
                OrderVO orderVO = new OrderVO();
                BeanUtils.copyProperties(order, orderVO);
                orderVO.setOrderDetailList(orderDetailList);
                list1.add(orderVO);
            }
        }
        return new PageResult(orders.getTotal(), list1);
    }


    /**
     * 订单详情
     *
     * @param id
     * @return
     */
    @Override
    public OrderVO getById(Long id) {
        //1.查询订单
        Orders orders = userOrderMapper.getByID(id);
        //2.查询订单明细
        List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(id);
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(orders, orderVO);
        orderVO.setOrderDetailList(orderDetailList);
        return orderVO;
    }


    /**
     * 取消订单
     *
     * @param id
     */
    @Override
    public void cancel(Long id) {
        //规则：
        // 1.假如是未支付或者未接单状态（并退款）可以直接取消
        //2.已结单或派送中，需要打电话与商家进行沟通
        //3.取消订单后将订单状态设置为已取消
        Orders order = userOrderMapper.getByID(id);
        if (order == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        //判断状态
        if (order.getStatus() > 2) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        //如果是已付款未结单
        if (order.getStatus().equals(Orders.TO_BE_CONFIRMED)) {
            //需要进行退款
            //修改状态为退款（相当于就是客户想退款）
            order.setPayStatus(Orders.REFUND);
        }
        order.setStatus(Orders.CANCELLED);
        order.setCancelReason("用户取消");
        userOrderMapper.update(order);
    }


    /**
     * 再来一单
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void repetition(Long id) {
        Long userId = BaseContext.getCurrentId();
        //1.查询订单详情
        List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(id);
        //将订单详情转换为购物车数据
        List<ShoppingCart> collect = orderDetailList.stream().map(
                orderDetail -> {
                    ShoppingCart shoppingCart = new ShoppingCart();
                    BeanUtils.copyProperties(orderDetail, shoppingCart);
                    shoppingCart.setUserId(userId);
                    shoppingCart.setCreateTime(LocalDateTime.now());
                    return shoppingCart;
                }
        ).collect(Collectors.toList());
        shoppingCartMapper.insertBatch(collect);
    }


}
